<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>china history</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
  <link rel="stylesheet" href="https://at.alicdn.com/t/c/font_3352173_n3ud4x0bnhf.css">
  <style>
  * {
    margin: 0px;
    padding: 0px;
    list-style: none;
    box-sizing: border-box;
    font-family: system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell, Noto Sans, sans-serif;
  }

  .lrcText {
    position: fixed;
    display: flex;
    justify-content: center;
    width: 100%;
    bottom: 20px;
    font-size: 22px;
    color: #00a8f2;
    z-index: 1;
  }

  .musicDisc {
    position: fixed;
    top: 15px;
    right: 15px;
    width: 32px;
    height: 32px;
  }

  .musicDisc .item {
    position: absolute;
    opacity: 0;
    top: 32px;
    right: 16px;
  }

  .musicDisc i {
    color: #666;
    font-size: 10px;
    position: absolute;
  }

  .musicDisc i.yf1 {
    animation: note-animation-y 3s cubic-bezier(.37, .16, .63, 1) 0s infinite;
  }

  .musicDisc i.yf2 {
    animation: note-animation-y 3s cubic-bezier(.37, .16, .63, 1) 1.3s infinite;
  }

  .musicDisc .item1 {
    animation: note-animation-x 3s ease-in-out 0s infinite, note-animation-opacity 3s linear 0s infinite;
  }

  .musicDisc .item2 {
    animation: note-animation-x 3s ease-in-out 1.3s infinite, note-animation-opacity 3s linear 1.3s infinite;
  }

  @keyframes note-animation-x {
    0% {
      transform: scale(.8) rotate(10deg) translate3d(-0.5rem, 0, 0);
    }
    55.6% {
      transform: scale(1.3) rotate(10deg) translate3d(0.5rem, 0, 0);
    }
    100% {
      transform: scale(1.3) translate3d(-0.5rem, 0, 0);
    }
  }

  @keyframes note-animation-y {
    0% {
      transform: translateZ(0);
    }
    100% {
      transform: translate3d(0, 1.2rem, 0);
    }
  }

  @keyframes note-animation-opacity {
    10% {
      opacity: 0;
    }

    85.3% {
      opacity: 1;
    }
    100% {
      opacity: 0;
    }
  }

  .nextprev {
    flex-shrink: 0;
    display: flex;
    align-items: center;
  }

  .nextprev i {
    font-size: 8px;
    color: #ccc;
    margin-right: 8px;
    cursor: pointer;
  }

  .nextprev i:first-child {
    margin-left: 14px;
  }

  .nextprev i.cur {
    color: #00a8f2;
  }

  .musicList {
    position: fixed;
    top: 47px;
    right: 15px;
    width: 186px;
    height: 132px;
    z-index: 1;
    font-size: 12px;
    background: #333;
    color: #888;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 12px;
  }

  .musicList ul {
    width: calc(100% - 10px);
    height: calc(100% - 10px);
    overflow-y: auto;
  }

  .musicList ul::-webkit-scrollbar-thumb {
    background: #888;
  }

  .musicList ul::-webkit-scrollbar {
    width: 4px;
  }

  .musicList ul::-webkit-scrollbar-track {
    background: #444;
  }

  .musicList li {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: 24px;
    cursor: pointer;
    padding: 0 5px;
    border-radius: 12px;
  }

  .musicList li.cur {
    background: #444;
    color: #00a8f2;
  }

  .musicList li .time {
    width: 32px;
    flex-shrink: 0;
    color: #999;
  }

  .musicList li .name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }


  .musicTool {
    position: fixed;
    top: 15px;
    right: 15px;
    width: 32px;
    height: 32px;
    border-radius: 32px;
    z-index: 99;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    background: #222;
    transition: all .2s;
    overflow: hidden;
  }

  .progress {
    position: absolute;
    height: 100%;
    background: #00a8f2;
    left: 0;
    z-index: -1;
    top: 0;
  }

  .musicTool .name {
    font-size: 12px;
    line-height: 12px;
    color: #999;
    flex-grow: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    padding: 0 10px;
  }

  .musicTool i.mp {
    cursor: pointer;
    font-size: 24px;
    color: #ccc;
    animation: rotate 6s infinite linear;
    margin-right: 4px;
  }

  .musicTool i.play {
    color: #00a8f2;
  }

  @keyframes rotate {
    from {
      transform: rotate(0deg);
    }

    to {
      transform: rotate(360deg);
    }
  }


  .h2 {
    font-size: 20px;
    font-weight: bold;
    color: #222;
  }

  body, #app {
    width: 100vw;
    height: 100vh;
    overflow: hidden;
    /*background: radial-gradient(#fff 10%, #d0d0d0);*/
  }

  body {
    background: url("");
    background-size: cover;
  }

  #app {
    position: relative;
  }

  .author {
    opacity: .02;
    position: absolute;
    left: 0%;
    top: 50%;
    white-space: nowrap;
    transform: translate(-0%, -50%);
    font-size: 60vw;
    animation: move 180s infinite linear;
  }

  @keyframes move {
    0% {
      transform: translate(-0%, -50%);
    }
    50% {
      transform: translate(-50%, -50%);
    }
    100% {
      transform: translate(-0%, -50%);
    }

  }


  .history {
    position: relative;
    height: 100%;
    display: flex;
    align-items: flex-end;
    user-select: none;
  }

  .history .line {
    position: absolute;
    height: 2px;
    background: #ddd;
    width: 100%;
    left: 0;
    top: 50%;
  }

  .history ul {
    display: flex;
    align-items: flex-end;
    padding-bottom: calc(50vh - 47px);
  }

  /*.history li:first-child {*/
  /*  margin-left: 84px;*/
  /*}*/

  /*.history li:last-child {*/
  /*  margin-right: 84px;*/
  /*}*/

  .history li {
    width: 62px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-end;
    color: #888;
    cursor: pointer;
    position: relative;
    transition: all .4s;
    z-index: 1;
    /*pointer-events: none;*/
    height: fit-content;
  }

  .history li:hover {

    transform: scale(1.1);
    z-index: 2;
  }


  .history li:hover .ms {
    display: block;
  }

  .history li .time {
    font-size: 12px;
    text-align: center;
    word-wrap: break-word;
  }


  .history li .dot {
    position: relative;
    display: flex;
    margin-top: 5px;
    margin-bottom: 10px;
  }

  .history li i {
    position: relative;
    z-index: 2;
  }


  .history li.lv1 .name {
    font-size: 34px;
    width: 34px;
    line-height: 34px;
    color: #00a8f2;
  }

  .history li.lv1 .dot, .history li.lv1 .time, .history li.lv2 .dot, .history li.lv2 .time, .history li.lv3 .dot, .history li.lv3 .time {
    color: #00a8f2;
  }

  .history li.lv1 .dot span, .history li.lv2 .dot span, .history li.lv3 .dot span {
    background: #00a8f2;
  }

  .history li.lv1 .dot span {
    width: 3px;
    margin-left: -1px;
  }

  .history li.lv2 .dot span {
    width: 2px;
    margin-left: -1px;
  }

  .history li.lv2 .name {
    font-size: 20px;
    width: 20px;
    line-height: 20px;
    color: #00a8f2;
  }

  .history li.lv3 .name {
    font-size: 16px;
    width: 16px;
    line-height: 16px;
    color: #00a8f2;
  }

  .history li.lv1 .dot {
    padding-top: 100px;
  }

  .history li.lv2 .dot {
    padding-top: 76px;
  }

  .history li.lv3 .dot {
    padding-top: 42px;
  }

  .history li.lv1 .dot i {
    font-size: 24px;
  }

  .history li.lv2 .dot i {
    font-size: 18px;
  }

  .history li.lv3 .dot i {
    font-size: 12px;
  }


  .history li.his {
    font-size: 12px;
    pointer-events: inherit;
  }

  .history li.his .name {
    width: 20px;
    padding: 3px;
    border: solid 1px #ccc;
    background: #fff;
  }


  .history li.his .dot {
    width: 16px;
    height: 16px;
    border-radius: 100%;
    border: solid 1px #ccc;
    background: #fff;
    margin: 12px 0 8px;
    transition: all .4s;
  }

  .history li.his.hot .name {
    border-color: #60c1ff;
    background: #60c1ff;
    color: #fff;
  }

  .history li.his .dot span {
    bottom: 8px;
    display: none;
  }

  .history li.hot {
    color: #60c1ff;
    z-index: 2;
  }

  .history li.hot .dot {
    background: #60c1ff;
    border-color: #60c1ff;
  }


  .history li .dot span {
    width: 1px;
    height: 100%;
    background: #ccc;
    display: block;
    position: absolute;
    left: 50%;
    bottom: 0;
  }

  .history li .ms {
    font-size: 12px;
    color: #888;
    position: absolute;
    background: #fff;
    box-shadow: 0 0 3px rgba(0, 0, 0, .3);
    border-radius: 12px;
    bottom: 65px;
    padding: 15px;
    z-index: 2;
    width: 210px;
    color: #444;
    display: none;
    line-height: 20px;
  }

  .history li .ms i {
    font-style: normal;
    color: #999;
  }

  .history li .ms:before {
    position: absolute;
    content: '';
    border-width: 8px;
    border-style: solid;
    border-color: #fff transparent transparent transparent;
    bottom: -15px;
    filter: drop-shadow(0 1px 1px rgba(0, 0, 0, .2));
    left: 50%;
    margin-left: -8px;
  }

  .win {
    width: 100%;
    height: 100%;
    position: fixed;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .win .mark {
    width: 100%;
    height: 100%;
    position: absolute;
    z-index: 1;
    background: rgba(0, 0, 0, .6);
  }

  .win .kuang {
    width: 720px;
    background: #fff;
    box-shadow: 0 0 13px rgba(0, 0, 0, .2);
    position: relative;
    z-index: 2;
    border-radius: 15px;
  }

  .win .kuang .ms {
    padding: 25px;
    line-height: 24px;
    color: #555;
    max-height: 550px;
    overflow-y: auto;
  }

  .win .kuang .ms .jc {
    display: flex;
    flex-wrap: wrap;
    padding: 15px;
    background: #f8f8f8;
    margin-bottom: 15px;
  }

  .win .kuang .ms .jc li {
    width: 50%;
    line-height: 34px;
  }

  .win .kuang .ms .jc li i {
    color: #aaa;
    font-style: normal;
  }

  .win .kuang .ms p {
    margin-bottom: 15px;
  }

  .win .kuang .ms p a, .win .kuang .ms b, .win .kuang .ms strong {
    color: #60c1ff;
    text-decoration: none;
  }

  .win .kuang .title {
    font-size: 34px;
    text-align: center;
    padding: 20px 0 20px;
    border-bottom: solid 1px #ddd;
    position: relative;
  }

  .win .kuang .title i {
    cursor: pointer;
    position: absolute;
    width: 40px;
    height: 40px;
    border-radius: 100%;
    right: -20px;
    background: #333;
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    top: -20px;
  }

  .st-enter-active, .st-leave-active {
    transition: all .6s;
  }

  .st-enter, .st-leave-to {
    opacity: 0;
  }

  .st-enter-to, .st-leave {
    opacity: 1;
  }

  @media screen and (max-width: 768px) {
    .win .kuang {
      width: 90%;
    }
  }

  input[type=color] {
    position: absolute;
    left: 10px;
    appearance: none;
    width: 20px;
    height: 20px;
    border-radius: 100%;
  }


  </style>
</head>

<body>
<div id="app">
  <div class="lrcText" v-if="isGeci" :style="{color:geciColor}">
    <input type="color" @change="getColor">
    {{curText}}
  </div>
  <div class="musicList" v-if="isList">
    <ul>
      <li v-for="(item,inx) in musicList" :class="{cur:inx==xh}" @click="play(inx)">
        <div class="name">{{inx+1}}:{{item.songName}}-{{item.songAuto}}</div>
        <div class="time">{{formatTime(item.duration)}}</div>
      </li>
    </ul>
  </div>
  <div class="musicDisc" v-if="isPlay">
    <div class="item item1">
      <i class="iconfont icon-yinfu yf1"></i>
    </div>
    <div class="item item2">
      <i class="iconfont icon-yinle1 yf2"></i>
    </div>
  </div>
  <div class="musicTool" :style="musicStyle" @click="gotoWhere">
    <div class="progress" :style="progressStyle" v-if="isPlay"></div>
    <div class="nextprev" v-if="isPlay">
      <i class="iconfont icon-ziyuan1" @click.stop="prev"></i>
      <i class="iconfont icon-geciweidianji" @click.stop="isGeci=!isGeci" :class="{cur:isGeci}"></i>
      <i class="iconfont icon-yijicaidan" @click.stop="isList=!isList" :class="{cur:isList}"></i>
      <i class="iconfont icon-ziyuan" @click.stop="next"></i>
    </div>
    <div class="name" v-if="isPlay">{{musicList[xh].songName}}-{{musicList[xh].songAuto}}</div>
    <i class="iconfont icon-yinle mp" :class="{play:isPlay}" :style="playStyle" @click.stop="play(xh)"></i>
  </div>
  <div class="author">china history</div>
  <transition name="st">
    <div class="win" v-if="show">
      <div class="mark"></div>
      <div class="kuang">
        <div class="title">{{nr.title}}<i class="icon-close iconfont" @mousedown.stop="show=false"
                                          @touchstart.stop="show=false"></i></div>
        <div class="ms" v-html="nr.ms"></div>
      </div>
    </div>
  </transition>
  <div class="history" :style="widthStyle" @mousedown="mousedown" @mousemove="mousemove" @mouseup="mouseup"
       @mouseleave="mouseleave" @touchstart="touchstart" @touchmove="touchmove" @touchend="touchend">
    <div class="line"></div>
    <ul ref="ul">
      <li></li>
      <li v-for="item in history"
          :class="{lv1:item.level===1,lv2:item.level===2,lv3:item.level===3,his:item.level==='history',hot:item.tj}"
          @click="tan(item)">
        <div class="name" v-if="item.name">{{item.name}}</div>
        <div class="dot" v-if="item.level==='history'"><span></span></div>
        <div class="dot" v-else><i class="iconfont icon-dingwei"></i><span></span></div>
        <div class="time" v-html="item.time"></div>
      </li>
      <li></li>
    </ul>
  </div>
</div>
<script src="https://leeao8.gitee.io/music/musicList_BF.js" type="text/javascript"></script>
<script src="player.js" type="text/javascript"></script>
<script src="history.js" type="text/javascript"></script>
<script src="vue.min.js" type="text/javascript"></script>
<script type="text/javascript">
new Vue({
    el: '#app',
    data: {
        history: history,
        scrollX: localStorage.getItem('scrollX') ? parseInt(localStorage.getItem('scrollX')) : 0,//拖动移动的距离
        saveX: localStorage.getItem('scrollX') ? parseInt(localStorage.getItem('scrollX')) : 0,//拖动后保存位置,很重要必须
        isDown: false,
        isClick: false,//这个是为了解决是点击还是mouseup冲突问题
        oldX: 0,
        sw: window.innerWidth,
        scrollW: 0,
        maxX: 0,
        moveX: 0,//移动端touchup没有event.targetTouches了，所以要用这个来存，为了统一，PC端也借助这个
        show: false,
        curContent: '',
        duration: 0,
        musicList: data.list,
        player: new QMplayer(),
        isPlay: false,
        isGeci: false,
        isList: false,
        xh: 0,//播放音乐序号
        curTime: 0, //播放當前時間
        lrcText: [],//当前歌曲对应的歌词
        geciColor: '#000'

    },
    mounted() {
        window.addEventListener("resize", () => {
            this.sw = window.innerWidth
        })
        document.addEventListener('keyup', (e) => {
            if (e.code === 'Escape') {
                this.show = false
            }
        })
        document.addEventListener('keydown', (e) => {
            if (e.code === 'ArrowLeft') {
                this.scrollX += 15
                if (this.scrollX > 0) {
                    this.scrollX = 0
                }

                this.saveX = this.scrollX
                localStorage.setItem('scrollX', this.scrollX)

            }
            if (e.code === 'ArrowRight') {
                this.scrollX -= 15
                if (this.scrollX < this.maxX) {
                    this.scrollX = this.maxX
                }
                this.saveX = this.scrollX
                localStorage.setItem('scrollX', this.scrollX)

            }
        })
        //音乐部分开始
        // 监听事件
        this.player.on("play", () => {
            this.xh = this.player.data.index//赋值当前歌曲的XH
            this.isPlay = true
        })
        this.player.on("pause", () => {
            this.isPlay = false
        })
        this.player.on("ended", () => {
            if (this.xh == this.musicList.length - 1) {
                this.next()
            }
        })
        this.player.on("timeupdate", () => {
            this.curTime = this.player.currentTime
        })

    },
    computed: {
        progressStyle() {
            if (this.player.duration) {
                let currentTime = this.player.currentTime
                let duration = this.player.duration
                return 'width:' + (currentTime / duration) * 100 + '%'
            } else {
                return 'width:0%'
            }

        },
        widthStyle() {
            return 'width:' + this.scrollW + 'px;transform:translateX(' + this.scrollX + 'px);transition-duration:' + this.duration + 'ms'
        },
        playStyle() {
            let aa = ''
            if (this.isPlay) {
                aa = 'animation-play-state:running'
            } else {
                aa = 'animation-play-state:paused'
            }
            return aa
        },
        musicStyle() {
            let aa = ''
            if (this.isPlay) {
                aa = 'width:186px'
            } else {
                aa = ''
            }
            return aa
        },
        curText() {
            if (this.lrcText) {
                let fi = this.lrcText.filter((el) => {
                    return el.cur
                })
                if (fi.length > 0) {
                    return fi[0].text
                }

            }
        }
    },
    watch: {
        isPlay: {
            immediate: true,
            handler(value) {
                if (value) {
                    this.progress()
                } else {
                    this.isList = false
                }
            }
        },
        xh: {
            immediate: true,
            handler(value) {
                this.lrcText = []
                //获取当前歌曲对应歌词
                fetch('lrc/' + this.musicList[value].lrc)
                    .then((response) => {
                        return response.text();
                    })
                    .then((myJson) => {
                        let line = myJson.split('\n');
                        line.forEach((el, xh) => {
                            let rs = el.split(']');
                            if (rs[1] == undefined) {
                                rs[1] = "";
                            }
                            this.lrcText.push({xh: xh + 1, btime: rs[0] + ']', text: rs[1]});
                        })
                    });
            }
        },
        sw: {
            immediate: true,
            handler(value) {
                setTimeout(() => {
                    this.scrollW = this.$refs.ul.scrollWidth
                    this.maxX = (this.scrollW - value) * -1
                    if (this.scrollX < this.maxX) {
                        this.scrollX = this.maxX
                        this.saveX = this.scrollX
                    }
                }, 1)
            }
        },
        isDown: {
            immediate: true,
            handler(value) {
                if (value) {
                    this.duration = 0
                } else {
                    this.duration = 400
                }

            }
        },
    },
    methods: {
        formatTime(value) {
            let fen = Math.floor(value / 60)
            let yu = Math.floor(value % 60)
            if (fen < 10) {
                fen = '0' + fen
            } else {
                fen = fen
            }
            if (yu < 10) {
                yu = '0' + yu
            } else {
                yu = yu
            }
            return fen + ':' + yu
        },
        gotoWhere() {
            if (this.isPlay) {
                let pos = event.pageX - event.currentTarget.offsetLeft
                let allW = event.currentTarget.scrollWidth
                this.player.currentTime = (pos / allW) * this.player.duration

            }

        },
        getColor() {
            this.geciColor = event.target.value
        },
        toSec(el) {//[00:12.52]类型时间转为秒函数
            let min = Number(el.btime.substr(1, 2));
            let sec = Number(el.btime.substring(4, el.btime.length - 1));
            let lastSec = min * 60 + sec;
            return lastSec
        },
        progress() {
            this.setinter = setInterval(() => {
                //歌词处理
                this.lrcText.forEach((el) => {
                    this.$set(el, 'cur', false)
                })
                let fi = this.lrcText.filter((el) => {
                    let lastSec = this.toSec(el);
                    let diff = this.curTime;
                    return diff - lastSec >= 0
                })
                if (fi[fi.length - 1]) {
                    this.$set(fi[fi.length - 1], 'cur', true)
                }
            }, 1)

        },
        play(index) {
            let musicList = []
            this.musicList.forEach((el) => {
                musicList.push(el.songUrl)
            })
            this.player.play(musicList, {index: index})
        },
        prev() {
            this.player.playPrev();
        },
        next() {
            this.player.playNext();
        },
        tan(item) {
            if (this.isClick) {
                if (item.level != 'history') {
                    this.scrollX = (event.currentTarget.offsetLeft - this.sw * 0.5) * -1
                    if (this.scrollX < this.maxX) {
                        this.scrollX = this.maxX
                    }
                    if (this.scrollX > 0) {
                        this.scrollX = 0
                    }
                    this.saveX = this.scrollX
                    localStorage.setItem('scrollX', this.scrollX)
                } else {
                    this.show = true
                    this.nr = item
                }
            }
        },
        huitan() {
            this.isDown = false
            if (this.scrollX > 0) {
                this.scrollX = 0
            }
            if (this.scrollX < this.maxX) {
                this.scrollX = this.maxX
            }
            this.saveX = this.scrollX
            localStorage.setItem('scrollX', this.scrollX)

        },
        mousedown() {
            this.isDown = true
            this.oldX = event.pageX
        },
        mousemove() {
            if (this.isDown) {
                let newX = event.pageX
                this.moveX = newX - this.oldX
                let dis = this.saveX + this.moveX
                if (dis > 0) {
                    dis = (this.saveX + this.moveX) * 0.2
                }

                if (dis < this.maxX) {
                    //dis= this.saveX + this.moveX+(maxX-(this.saveX + this.moveX))*0.8
                    dis = (this.saveX + this.moveX) * 0.2 + 0.8 * this.maxX
                }
                this.scrollX = dis
            }

        },
        mouseup() {
            if (Math.abs(event.pageX - this.oldX) > 0) {
                this.isClick = false
            } else {
                this.isClick = true
            }
            this.huitan()
        },
        mouseleave() {
            this.huitan()
        },
        touchstart() {
            this.isDown = true
            this.oldX = event.targetTouches[0].pageX
        },
        touchmove() {
            if (this.isDown) {
                let newX = event.targetTouches[0].pageX
                this.moveX = newX - this.oldX
                let dis = this.saveX + this.moveX
                if (dis > 0) {
                    dis = (this.saveX + this.moveX) * 0.2
                }

                if (dis < this.maxX) {
                    dis = (this.saveX + this.moveX) * 0.2 + 0.8 * this.maxX
                }

                this.scrollX = dis
            }
        },
        touchend() {
            if (Math.abs(this.moveX) > 0) {
                this.isClick = false
            } else {
                this.isClick = true
            }
            this.huitan()
        },
    }
})
</script>
</body>
</html>
